package visualizer.client.widgets.controlPanel;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.InputElement;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import visualizer.client.event.ControlPanelEventHandler;
import visualizer.client.utils.ScaleInfo;

/**
 * User: DDovzhenko
 * Date: 30.12.13
 * Time: 15:17
 */
public class ControlPanelView extends Composite implements ControlPanelPresenter.Display {

    @UiField
    DivElement prevStepButton;
    @UiField
    DivElement nextStepButton;
    @UiField
    DivElement toStartButton;
    @UiField
    DivElement toEndButton;
    @UiField
    DivElement messageBox;
    @UiField
    DivElement inputBox;
    @UiField
    DivElement beginButton;
    @UiField
    DivElement buttons;
    @UiField
    DivElement input;
    @UiField
    SpanElement rangeValue;
    @UiField
    InputElement rangeInput;
    @UiField
    DivElement slider;
    @UiField
    DivElement animationButton;

    ControlPanelEventHandler handler;
    private int animationSpeed = 50;
    private boolean isAnimationStarted = false;

    public ControlPanelView() {
        initWidget(ourUiBinder.createAndBindUi(this));
        initListeners();
    }

    private void initListeners() {
        DOM.sinkEvents(prevStepButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(prevStepButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                if (isAnimationStarted) {
                    return;
                }
                handler.onPrevStepClick();
            }
        });
        DOM.sinkEvents(nextStepButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(nextStepButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                if (isAnimationStarted) {
                    return;
                }
                handler.onNextStepClick();
            }
        });
        DOM.sinkEvents(toStartButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(toStartButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                if (isAnimationStarted) {
                    return;
                }
                handler.onToStartClick();
            }
        });
        DOM.sinkEvents(toEndButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(toEndButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                if (isAnimationStarted) {
                    return;
                }
                handler.onToEndClick();
            }
        });
        DOM.sinkEvents(beginButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(beginButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                if (isAnimationStarted) {
                    return;
                }
                String valueStr = input.getInnerHTML();
                if (valueStr.equals("<br>")) return;
                String value = valueStr.split("<br>")[0];
                if (value.matches("[0-9]*")) {
                    handler.onBeginClick(Integer.valueOf(value));
                }
            }
        });
        DOM.sinkEvents(input.<Element>cast(), Event.ONKEYDOWN);
        DOM.setEventListener(input.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                int charCode = event.getCharCode();
                if (charCode != 0 && (charCode < 48 || charCode > 57 || input.getInnerHTML().length() > 7)) {
                    event.preventDefault();
                }
            }
        });
        DOM.sinkEvents(rangeInput.<Element>cast(), Event.ONCLICK | Event.ONMOUSEOVER | Event.ONMOUSEOUT);
        DOM.setEventListener(rangeInput.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                switch (event.getTypeInt()) {
                    case Event.ONCLICK:
                        String value = rangeInput.getValue();
                        rangeValue.setInnerText(value);
                        animationSpeed = Integer.parseInt(value);
                        handler.onAnimationSpeedChange(animationSpeed);
                    case Event.ONMOUSEOVER:
                        rangeValue.addClassName("active");
                        break;
                    case Event.ONMOUSEOUT:
                        rangeValue.removeClassName("active");
                        break;
                }
            }
        });
        DOM.sinkEvents(animationButton.<Element>cast(), Event.ONCLICK);
        DOM.setEventListener(animationButton.<Element>cast(), new EventListener() {
            @Override
            public void onBrowserEvent(Event event) {
                setAnimation(!isAnimationStarted);
            }
        });
    }

    @Override
    public void onResize() {
        this.getElement().setAttribute("style", "-moz-transform: " + ScaleInfo.getInstance().getMozTransformScale());
    }

    @Override
    public void setEventListener(ControlPanelEventHandler handler) {
        this.handler = handler;
    }

    @Override
    public void setMessage(String message) {
        messageBox.setInnerHTML(message);
    }

    @Override
    public void setInputFieldVisible(boolean isVisible) {
        if (isVisible) {
            inputBox.getStyle().setVisibility(Style.Visibility.VISIBLE);
            input.setInnerHTML("<br>");
        } else {
            inputBox.getStyle().setVisibility(Style.Visibility.HIDDEN);
            input.setInnerHTML("0");
        }
    }

    @Override
    public void setBeginButtonText(String text) {
        beginButton.setInnerHTML(text);
    }

    @Override
    public int getAnimationSpeed() {
        return animationSpeed;
    }

    @Override
    public void setAnimation(boolean isAnimate) {
        isAnimationStarted = isAnimate;
        if (isAnimationStarted) {
            animationButton.setInnerText("Стоп");
        } else {
            animationButton.setInnerText("Старт");
        }
        handler.onAnimationChange(isAnimationStarted);
    }

    //------------- UI Binder --------------
    interface ControlPanelUiBinder extends UiBinder<HTMLPanel, ControlPanelView> { }
    private static ControlPanelUiBinder ourUiBinder = GWT.create(ControlPanelUiBinder.class);
}